package com.ns.sbs.oauth.rent.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ns.core.utils.sg.ResultError;
import com.ns.sbs.oauth.acc.entry.Acc2Server;
import com.ns.sbs.oauth.acc.mapper.Acc2ServerMapper;
import com.ns.sbs.oauth.rent.dto.RentPageDto;
import com.ns.sbs.oauth.rent.dto.RentPermissionDto;
import com.ns.sbs.oauth.rent.entry.RentEntry;
import com.ns.sbs.oauth.rent.entry.RentPermissionEntry;
import com.ns.sbs.oauth.rent.entry.RentServerEntry;
import com.ns.sbs.oauth.rent.mapper.RentEntryMapper;
import com.ns.sbs.oauth.rent.mapper.RentPermissionMapper;
import com.ns.sbs.oauth.rent.mapper.RentServerMapper;
import com.ns.sbs.oauth.rent.vo.RentEntryVO;
import com.ns.sbs.oauth.role.entry.RoleEntry;
import com.ns.sbs.oauth.role.mapper.RoleMapper;
import com.ns.sbs.oauth.role.vo.RoleEntryVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 角色业务实现
 *
 * @author : liaowei
 * @version : v1.0.0
 * @since : 2024/8/24 22:03
 **/
@Service
@RequiredArgsConstructor
public class RentServiceImpl extends ServiceImpl<RentEntryMapper, RentEntry> implements IRentService {

    private final RentEntryMapper mapper;

    private final RentServerMapper serverMapper;

    private final RentPermissionMapper rentPermissionMapper;

    private final Acc2ServerMapper acc2ServerMapper;

    private final RoleMapper roleMapper;

    @Override
    public Page<RentEntryVO> getList(RentPageDto dto) {
        Page<RentEntryVO> list = mapper.getList(dto, new Page<>(dto.getCurrent(), dto.getSize()));
        List<RentEntryVO> records = list.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            for (RentEntryVO rs : records) {
                rs.setSids(serverMapper.getByRid(rs.getId()));
            }
            list.setRecords(records);
        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void assistPermission(RentPermissionDto dto) {
        // 校验权限
        if (CollectionUtils.isEmpty(dto.getPermissions())) {
            throw new ResultError("请选择服务权限！");
        }
        // 校验租户信息
        RentEntry rentEntry = mapper.selectById(dto.getId());
        if (Objects.isNull(rentEntry)) {
            throw new ResultError("未知租户信息！");
        }

        List<RentPermissionEntry> permissions = new ArrayList<>();
        Set<Long> sids = new HashSet<>();

        // 封装保存租户权限数据
        getPermission(dto, sids, permissions);

        // 分配租户服务
        assistRentServer(dto, sids);

        // 分配租户权限 先删除再新增
        if (!CollectionUtils.isEmpty(permissions)) {
            rentPermissionMapper.delByRid(rentEntry.getId());
            rentPermissionMapper.insert(permissions);
        }

        // 创建服务默认角色
        createDefaultRole(dto.getId(), sids, rentEntry.getAccId());
    }

    /**
     * 分配租户服务
     *
     * @param dto
     * @param sids
     */
    private void assistRentServer(RentPermissionDto dto, Set<Long> sids) {

        if (!CollectionUtils.isEmpty(sids)) {
            List<RentServerEntry> rse = new ArrayList<>();
            for (Long sid : sids) {
                // 租户服务
                RentServerEntry rs = new RentServerEntry();
                rs.setRid(dto.getId());
                rs.setSid(sid);
                rse.add(rs);
            }
            serverMapper.delByRid(dto.getId());
            serverMapper.insert(rse);
        }
    }

    /**
     * 封装数据
     *
     * @param dto         租户权限
     * @param sids        返回服务
     * @param permissions 返回权限
     */
    private static void getPermission(RentPermissionDto dto, Set<Long> sids, List<RentPermissionEntry> permissions) {
        for (List<Long> permission : dto.getPermissions()) {
            if (Objects.isNull(permission.get(0))) {
                throw new ResultError("数据异常，请联系管理员!");
            }
            sids.add(permission.get(0));
            // 租户权限
            RentPermissionEntry rps = new RentPermissionEntry();
            rps.setRid(dto.getId());
            rps.setSid(permission.get(0));
            switch (permission.size()) {
                case 2:
                    rps.setOne(permission.get(1));
                    break;
                case 3:
                    rps.setOne(permission.get(1));
                    rps.setTwo(permission.get(2));
                    break;
                case 4:
                    rps.setOne(permission.get(1));
                    rps.setTwo(permission.get(2));
                    rps.setThree(permission.get(3));
                    break;
                case 5:
                    rps.setOne(permission.get(1));
                    rps.setTwo(permission.get(2));
                    rps.setThree(permission.get(3));
                    rps.setFour(permission.get(4));
                    break;
                default:
                    throw new IllegalStateException("权限超出范围: " + permission.size());
            }
            permissions.add(rps);
        }
    }


    /**
     * 创建服务默认角色
     * 如果已分配则跳过
     *
     * @param rid   租户id
     * @param sids  服务id
     * @param accId 默认账户
     */
    private void createDefaultRole(Long rid, Set<Long> sids, Long accId) {
        if (!CollectionUtils.isEmpty(sids)) {
            for (Long sid : sids) {
                RoleEntryVO role = roleMapper.getRoleByAccIdAndSidAndRid(accId, sid, rid);
                if (Objects.isNull(role)) {
                    // 默认角色 锁定
                    RoleEntry r = new RoleEntry();
                    r.setName("默认角色");
                    r.setLevel(0);
                    r.setIsLock(1);
                    r.setStatus(1);
                    r.setSid(sid);
                    r.setRid(rid);
                    r.setSort(1l);
                    if (!roleMapper.insertOrUpdate(r)) {
                        throw new ResultError("租户角色初始化失败，请稍后重试！");
                    }
                    // 绑定账户和角色
                    Acc2Server acc2Server = new Acc2Server();
                    acc2Server.setSid(r.getSid());
                    acc2Server.setRoleId(r.getId());
                    acc2Server.setAccId(accId);
                    acc2ServerMapper.insert(acc2Server);
                }
            }
        }
    }

    @Override
    public List<List<String>> getRentPermission(Long rid) {
        List<List<String>> pms = new ArrayList<>();
        List<RentPermissionEntry> permissionEntries = rentPermissionMapper.selectByRid(rid);
        if (Objects.nonNull(permissionEntries)) {
            for (RentPermissionEntry permissionEntry : permissionEntries) {
                List<String> pm = new ArrayList<>();
                pm.add(String.valueOf(permissionEntry.getSid()));
                if (Objects.nonNull(permissionEntry.getOne())) {
                    pm.add(String.valueOf(permissionEntry.getOne()));
                }
                if (Objects.nonNull(permissionEntry.getTwo())) {
                    pm.add(String.valueOf(permissionEntry.getTwo()));
                }
                if (Objects.nonNull(permissionEntry.getThree())) {
                    pm.add(String.valueOf(permissionEntry.getThree()));
                }
                if (Objects.nonNull(permissionEntry.getFour())) {
                    pm.add(String.valueOf(permissionEntry.getFour()));
                }
                pms.add(pm);
            }
        }
        return pms;
    }
}
